package com.chungkui.bond.microservice.client;

import com.chungkui.bond.common.core.bean.BondLine;
import com.chungkui.bond.common.core.bean.BondNode;
import com.chungkui.bond.common.core.constant.MicroserviceConstants;
import com.chungkui.bond.common.core.utils.FeignClientParseUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.List;
import java.util.Map;


@Configuration
public class InitRelationship implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;
    @Value("${spring.application.name}")
    private String appname;
    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    private final BondNode bondNode = new BondNode();

    @Override
    public void afterPropertiesSet() throws Exception {
        // 根容器为Spring容器
        bondNode.setId(appname);
        bondNode.setName(appname);
        List<BondLine> lines = Lists.newArrayList();
        Map<String, Object> beans = applicationContext.getBeansWithAnnotation(FeignClient.class);
        if (!StringUtils.equals(MicroserviceConstants.AUTH_MANAGER_SERVER, appname) && MapUtils.isNotEmpty(beans)) {
            for (Object bean : beans.values()) {
                lines.add(new BondLine(appname, FeignClientParseUtil.getName(bean)));
            }
            bondNode.setBondLines(lines);
        }
        getAllApi();
    }

    public void getAllApi() {
        // 获取url与类和方法的对应信息
        List<Map<String,String>> permissions=Lists.newArrayList();
        Map<RequestMappingInfo, HandlerMethod> handlerMethods = handlerMapping.getHandlerMethods();
        for (Map.Entry<RequestMappingInfo, HandlerMethod> m : handlerMethods.entrySet()) {
            RequestMappingInfo info = m.getKey();
            Map<String, String> map = Maps.newHashMap();
            HandlerMethod method = m.getValue();
            PatternsRequestCondition p = info.getPatternsCondition();
            for (String url : p.getPatterns()) {
                map.put(url, method.getMethod().getName());
            }
            permissions.add(map);
        }
        bondNode.setUrls(permissions);
    }

    public BondNode getBondNode() {
        return bondNode;
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.applicationContext = context;
    }

}